feat(openai-official): add OpenAI Responses API module - #3078
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
There are correctness/usability issues in provider configuration and connection-field validation (env base URL resolution and blank-value normalization) that should be fixed before merging.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR introduces a new model extension module, agentscope-extensions-model-openai-official, integrating OpenAI models via the official OpenAI Java SDK against the Responses API, and wires it into docs, distributions, and the e2e harness.
Changes:
- Adds the
openai-officialprovider implementation (request mapping, response parsing, streaming assembly, error translation, credential type, SPI registration). - Updates distributions/BOM and extensions aggregator to include the new module, and adds e2e provider coverage.
- Updates v2 docs (EN/ZH) and TOC to document the new provider and module.
File summaries
| File | Description |
|---|---|
| docs/v2/zh/integration/overview.md | Adds openai-official provider row to the ZH integration overview table. |
| docs/v2/zh/integration/model/openai-official.md | New ZH provider doc page for the official SDK / Responses API module. |
| docs/v2/zh/integration/model/index.md | Links the new ZH provider doc in the model index. |
| docs/v2/zh/docs/building-blocks/model.md | Updates ZH “model building blocks” doc to include the new module/provider references. |
| docs/v2/zh/docs/building-blocks/agent.md | Mentions openai-official as a supported ModelRegistry provider in ZH agent docs. |
| docs/v2/en/integration/overview.md | Adds openai-official provider row to the EN integration overview table. |
| docs/v2/en/integration/model/openai-official.md | New EN provider doc page for the official SDK / Responses API module. |
| docs/v2/en/integration/model/index.md | Links the new EN provider doc in the model index. |
| docs/v2/en/docs/building-blocks/model.md | Updates EN “model building blocks” doc to include the new module/provider references. |
| docs/v2/en/docs/building-blocks/agent.md | Mentions openai-official as a supported ModelRegistry provider in EN agent docs. |
| docs/_toc.yml | Adds TOC entries for the new EN/ZH provider doc pages. |
| agentscope-extensions/agentscope-extensions-model/pom.xml | Enables the new agentscope-extensions-model-openai-official module in the extensions reactor build. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/TestSdkFixtures.java | Shared SDK object/exception fixtures for unit tests. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/ResponsesStreamingAssemblerTest.java | Unit tests for streaming event assembly to ChatResponse chunks. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/ResponsesResponseParserTest.java | Unit tests for non-streaming Response → ChatResponse parsing. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/ResponsesMultiAgentFormatterTest.java | Unit tests for multi-agent conversation merging/formatting. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/ResponsesHelperTest.java | Unit tests for metadata/usage extraction helpers. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/OpenAISdkClientFactoryTest.java | Unit tests for official SDK client construction and error wrapping. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/OpenAIResponsesChatModelTest.java | Unit tests for streaming/non-streaming flows, retry predicate behavior, and builder boundaries. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/OpenAIOfficialModelProviderTest.java | Unit tests for SPI provider supports/create behavior and advanced options. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/OpenAIOfficialModelExceptionTest.java | Unit tests for provider exception type and retryable-status classification. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/OpenAIErrorTranslatorTest.java | Unit tests for SDK exception translation coverage. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/test/java/io/agentscope/extensions/model/openaiofficial/credential/OpenAIOfficialCredentialTest.java | Unit tests for credential JSON round-tripping and validation. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/resources/META-INF/services/io.agentscope.core.model.spi.ModelProvider | Registers OpenAIOfficialModelProvider via ServiceLoader. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/ResponsesStreamingAssembler.java | Implements Responses API streaming event → incremental ChatResponse assembly. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/ResponsesResponseParser.java | Parses non-streaming SDK Response objects into ChatResponse. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/ResponsesRequestMapper.java | Maps AgentScope history/options/tools into SDK ResponseCreateParams. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/ResponsesMultiAgentFormatter.java | Implements multi-agent history grouping/merge into Responses API input items. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/ResponsesHelper.java | Extracts response metadata and usage into AgentScope-friendly structures. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/OpenAISdkClientFactory.java | Centralizes OpenAI SDK client creation with retries disabled and optional headers/timeout. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/OpenAIResponsesChatModel.java | Main ChatModelBase implementation for Responses API (streaming + non-streaming). |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/OpenAIOfficialModelProvider.java | Adds SPI provider supporting openai-official:<model> resolution. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/OpenAIOfficialModelException.java | Provider-specific exception type implementing ModelHttpException. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/OpenAIOfficialConstants.java | Centralizes provider id, metadata keys, and additionalBodyParams whitelist. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/OpenAIErrorTranslator.java | Translates SDK exceptions into OpenAIOfficialModelException. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/credential/OpenAIOfficialCredential.java | Adds credential type for the new provider. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/pom.xml | New module POM with openai-java dependency and test deps. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-e2e-tests/src/test/java/io/agentscope/core/e2e/providers/OpenAIOfficialResponsesProvider.java | Adds e2e provider(s) for official SDK Responses API path. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-e2e-tests/src/test/java/io/agentscope/core/e2e/ProviderFactory.java | Registers the new e2e providers in the factory list. |
| agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-e2e-tests/pom.xml | Adds test-scope dependency on the new openai-official module. |
| agentscope-distribution/agentscope-bom/pom.xml | Adds the new module to the published BOM. |
| agentscope-distribution/agentscope-all/pom.xml | Adds the new module as an optional dependency to the “all” distribution. |
| agentscope-core/src/main/java/io/agentscope/core/model/ModelUtils.java | Wraps timeouts with a TimeoutException cause for retry predicates to detect. |
| agentscope-core/src/main/java/io/agentscope/core/model/ModelContextWindows.java | Adds context window mappings for new OpenAI/GLM model names. |
Review details
Suppressed comments (2)
agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/OpenAIResponsesChatModel.java:175
- validateConnectionFields also treats a blank baseUrl as an override mismatch (null vs ""), but OpenAISdkClientFactory already normalizes blank baseUrl to “use SDK default”. This can incorrectly fail-fast on semantically equivalent values.
String effectiveBaseUrl = effectiveOptions.getBaseUrl();
if (effectiveBaseUrl != null && !Objects.equals(effectiveBaseUrl, baseUrl)) {
throw new OpenAIOfficialModelException(
agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-e2e-tests/src/test/java/io/agentscope/core/e2e/providers/OpenAIOfficialResponsesProvider.java:91
- Same mismatch here: the Javadoc says “GPT-5.4-mini” but the provider uses "gpt-5.4".
/** GPT-5.4-mini with Multi-Agent Formatter. */
- Files reviewed: 46/46 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
LGTM |
| <artifactId>agentscope-extensions-model-openai</artifactId> | ||
| <version>${project.version}</version> | ||
| </dependency> | ||
| <!-- <dependency>--> |
| <dependency> | ||
| <groupId>io.agentscope</groupId> | ||
| <artifactId>agentscope-extensions-model-openai-official</artifactId> | ||
| <scope>compile</scope> |
There was a problem hiding this comment.
这种直接打包进去吗?还是应该由用户提供?
遵循了既有模式,现有的其它模型厂商模块也都在里面
97b8f26 to
30a9821
Compare
Add agentscope-extensions-model-openai-official module integrating OpenAI models via the official OpenAI Java SDK (com.openai:openai-java) against the Responses API. Includes request mapping, response parsing, streaming assembly, error translation, credential type, SPI registration, e2e test provider, bilingual docs, and distribution/BOM updates. Resolve documentation conflicts from Mintlify migration (#3081): - Replace deleted _toc.yml with docs.json entries - Adapt agent.md/index.md/overview.md to Mintlify syntax - Add Mintlify front matter to openai-official.md pages
Aias00
left a comment
There was a problem hiding this comment.
已审。重点检查了新增 openai-official Responses 模块的请求映射、非流式解析、流式事件拼装、usage/metadata/finishReason、工具调用回放、错误转换、provider SPI、BOM/distribution 接入和相关测试覆盖。\n\n本地验证:mvn -pl agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official -am test -DskipITs 通过,274 tests, 0 failures/errors, 2 skipped。\n\n未发现需要阻塞合并的问题。
Aias00
left a comment
There was a problem hiding this comment.
Thanks for the large integration. I found one release-blocking issue in the all-in-one distribution: the new module is present in the shaded jar, but its ModelProvider service entry is not merged, so ModelRegistry cannot discover openai-official models when users depend on the agentscope artifact.
Verification run locally on PR head 0bcf01970ce985d0f973c81fefc9b30e241ed9fe:
mvn -pl agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official -am testpassed: 274 tests, 0 failures, 2 skippedmvn -pl agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-e2e-tests -am test-compile -DskipTestspassedbash .github/scripts/check-shade-and-bom-sync.shpassedmvn -pl agentscope-distribution/agentscope-all -am package -DskipTestspassed, but emitted the overlappingMETA-INF/services/io.agentscope.core.model.spi.ModelProviderwarning; inspecting the resulting jar confirmed the new provider is missing from the service descriptor.
| <!-- </dependency>--> | ||
| <dependency> | ||
| <groupId>io.agentscope</groupId> | ||
| <artifactId>agentscope-extensions-model-openai-official</artifactId> |
There was a problem hiding this comment.
[HIGH] Adding this module to agentscope-all currently packages the classes but does not make the provider discoverable. The shade build warns that multiple model modules define META-INF/services/io.agentscope.core.model.spi.ModelProvider, and the generated agentscope-2.0.3-SNAPSHOT.jar keeps only the existing OpenAI entries: unzip -p agentscope-distribution/agentscope-all/target/agentscope-2.0.3-SNAPSHOT.jar META-INF/services/io.agentscope.core.model.spi.ModelProvider does not include io.agentscope.extensions.model.openaiofficial.OpenAIOfficialModelProvider, even though the class is present. Users depending on the advertised all-in-one agentscope artifact will therefore fail to resolve openai-official:<model> through ModelRegistry. Please configure the shade plugin to merge service descriptors, for example with org.apache.maven.plugins.shade.resource.ServicesResourceTransformer, and add a packaging assertion or smoke test that the shaded jar service file contains this provider.
Aias00
left a comment
There was a problem hiding this comment.
Requesting changes based on two concrete correctness issues.
[HIGH] Multi-agent formatter drops encrypted reasoning replay
File: agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/ResponsesMultiAgentFormatter.java (line 175)
When OpenAIResponsesChatModel is configured with ResponsesMultiAgentFormatter, all history mapping goes through formatter::formatHistory. For an ordinary assistant turn that contains ThinkingBlock plus openai.reasoning.encrypted_content metadata, determineGroupType classifies it as AGENT_CONVERSATION; mergeAgentConversation then rewrites it into a user <history> message and processMessage only appends the visible thinking/text content. It never calls ResponsesRequestMapper.mapAssistantMessage, so no ResponseReasoningItem with encrypted_content is sent on the next request.
This breaks the PR's documented reasoning replay behavior exactly for the sample configuration that combines reasoning with ResponsesMultiAgentFormatter. I verified with a minimal probe: the formatted history for user -> assistant(thinking + encrypted metadata) -> user produced items=1 reasoning=0 easy=1.
Why tests miss it: CrossTurnTest verifies encrypted replay only with the default mapper, and ResponsesMultiAgentFormatterTest covers thinking text but never asserts that encrypted reasoning metadata is preserved.
Suggested fix: make formatter preserve assistant messages with openai.reasoning.encrypted_content as Responses reasoning replay items, or classify them into a passthrough path that delegates to ResponsesRequestMapper.mapAssistantMessage. Add a regression test that builds OpenAIResponsesChatModel with new ResponsesMultiAgentFormatter() and asserts the second-turn ResponseCreateParams.input contains a reasoning item with the encrypted content.
[MEDIUM] Per-schema strict mode is ignored for JSON schema response formats
File: agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official/src/main/java/io/agentscope/extensions/model/openaiofficial/ResponsesRequestMapper.java (line 185)
JsonSchema already exposes getStrict(), but the Responses mapper only sets schemaBuilder.strict(...) from the builder-level strictJsonSchema. A caller using ResponseFormat.jsonSchema(JsonSchema.builder().strict(true).build()) silently gets a request without strict: true unless they also set the model builder flag.
Why tests miss it: the tests only cover builder-level strictJsonSchema; there is no test where JsonSchema.strict(true) is set on the response format itself.
Suggested fix: resolve strict as schema.getStrict() != null ? schema.getStrict() : strictJsonSchema, then set it when non-null. Add a test that schema-level strict is propagated and that builder-level remains a fallback.
Validation run:
mvn -pl agentscope-extensions/agentscope-extensions-model/agentscope-extensions-model-openai-official -am test -DskipITspassed: 274 tests, 0 failures, 2 skipped.- Java LSP diagnostics were unavailable in this environment; the exposed diagnostic tool runs
npx tsc, so Maven compile/tests were used as the Java diagnostic substitute. ast-grepwas not installed; I usedrgfor hardcoded secret/debug/empty-catch/problem-pattern scanning.
Aias00
left a comment
There was a problem hiding this comment.
已复核 PR head 0bcf019。重点检查了 openai-official Responses 模块的请求映射、ReasoningContext metadata 持久化与后续 encrypted reasoning replay、流式 terminal metadata/usage 聚合、工具调用回放、provider SPI、BOM/distribution 接入和 retry 配置组合;未发现需要阻塞合并的问题。\n\nGitHub checks 当前通过:Java build ubuntu/windows、Check License、Check Module Sync、Codecov、CLA、Mintlify validate。\n\n结论:APPROVE。
Aias00
left a comment
There was a problem hiding this comment.
Requesting changes after re-checking PR head 0bcf019. I found release-blocking correctness issues that should be fixed before merge.
[HIGH] Multi-agent formatter drops encrypted reasoning replay
OpenAIResponsesChatModel sends all history through formatter::formatHistory when a ResponsesMultiAgentFormatter is configured (OpenAIResponsesChatModel.java:112-122). In that path, ordinary assistant messages are classified as AGENT_CONVERSATION unless they contain tool blocks (ResponsesMultiAgentFormatter.java:172-181), and mergeAgentConversation rewrites them into a user <history> message (ResponsesMultiAgentFormatter.java:209-237). processMessage then serializes ThinkingBlock as visible text (ResponsesMultiAgentFormatter.java:305-312) and never delegates to ResponsesRequestMapper.mapAssistantMessage, which is the only code path that emits the Responses reasoning replay item from openai.reasoning.encrypted_content metadata (ResponsesRequestMapper.java:433-445, ResponsesRequestMapper.java:477-493).
This breaks stateless reasoning replay exactly for the documented reasoning + multi-agent formatter usage. Please preserve assistant messages with encrypted reasoning metadata as Responses reasoning input items, or route them through a passthrough/delegation path, and add a regression test that configures OpenAIResponsesChatModel with new ResponsesMultiAgentFormatter() and asserts second-turn input contains the encrypted ResponseReasoningItem.
[MEDIUM] Schema-level strict mode is ignored for JSON schema structured output
JsonSchema exposes strict (JsonSchema.java:91-96), but ResponsesRequestMapper only writes schemaBuilder.strict(...) from the model-level strictJsonSchema flag (ResponsesRequestMapper.java:178-187). A caller setting ResponseFormat.json_schema with JsonSchema.strict(true) silently gets a request without strict: true unless they also configure the model builder flag.
Please resolve strict as schema-level first, then builder-level fallback, e.g. schema.getStrict() != null ? schema.getStrict() : strictJsonSchema, and add tests for schema-level override plus builder-level fallback.
[HIGH] all-in-one shaded artifact can lose ModelProvider service registration
The new module is added to agentscope-all (agentscope-all/pom.xml:111-116) and has its own SPI file (agentscope-extensions-model-openai-official/src/main/resources/META-INF/services/io.agentscope.core.model.spi.ModelProvider:1). But the shade config only includes artifacts and has no ServicesResourceTransformer or equivalent service merge (agentscope-all/pom.xml:449-466). There are multiple model-provider service descriptors across extension modules, so the shaded jar can keep only one descriptor and drop OpenAIOfficialModelProvider, making ModelRegistry discovery fail for users depending on the all-in-one agentscope artifact.
Please add a service resource transformer to the shade plugin and a packaging regression check that the shaded jar's META-INF/services/io.agentscope.core.model.spi.ModelProvider contains io.agentscope.extensions.model.openaiofficial.OpenAIOfficialModelProvider.
CI is green, but these are behavioral/package correctness issues not covered by the current checks.
Aias00
left a comment
There was a problem hiding this comment.
One additional blocking issue affects the default formatter path as well.
[HIGH] The production ReActAgent path discards encrypted reasoning metadata before the next turn
ResponsesResponseParser stores openai.reasoning.encrypted_content only in the terminal ChatResponse.metadata (lines 105-106), and the streaming path does the same in ResponsesStreamingAssembler (lines 261-263). However, the production consumer, ReasoningContext.processChunk, never reads chunk.getMetadata(); buildFinalMessage() creates a fresh metadata map containing only MessageMetadataKeys.CHAT_USAGE. The resulting assistant Msg therefore cannot contain the key that ResponsesRequestMapper.mapAssistantMessage looks up at lines 434-444.
As a result, encrypted reasoning replay is unreachable through a normal ReActAgent call even without ResponsesMultiAgentFormatter. This is particularly important for stateless reasoning/tool-call loops, where the reasoning item from the prior response must be sent back with the function-call output. The current cross-turn tests miss this because they manually construct an AssistantMessage with openai.reasoning.encrypted_content already present instead of exercising ChatResponse -> ReasoningContext -> Msg -> next request.
Please preserve the terminal response metadata in the final assistant message (or place the replay data on a content block and ensure its accumulator preserves it), and add a ReActAgent-level two-iteration regression test that captures the second ResponseCreateParams and asserts it contains the prior encrypted reasoning item.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
|
|
||
| @Override | ||
| protected ReActAgent.Builder doCreateAgentBuilder(String name, Toolkit toolkit, String apiKey) { | ||
| String baseUrl = System.getenv(BASE_URL_ENV); |
There was a problem hiding this comment.
这个只支持通过系统环境变量获取吗?
为什么不是从 spring 生命周期中的配置获取?
|
|
||
| @Override | ||
| public String getProviderName() { | ||
| return "OpenAI-Official"; |
|
|
||
| @Override | ||
| public String getProviderName() { | ||
| return "OpenAI-Official (Multi-Agent)"; |
| if (current instanceof OpenAIIoException | ||
| || current instanceof OpenAIRetryableException) { | ||
| return true; | ||
| } | ||
|
|
||
| if (current instanceof IOException) { | ||
| return true; | ||
| } | ||
|
|
||
| if (current instanceof TimeoutException) { | ||
| return true; | ||
| } |
| OpenAIOkHttpClient.Builder builder = | ||
| OpenAIOkHttpClient.builder().apiKey(apiKey).maxRetries(0); | ||
|
|
||
| if (baseUrl != null && !baseUrl.isBlank()) { |
There was a problem hiding this comment.
baseUrl.isNotBlank() 会不会好点?
Summary
This PR adds a new model extension module,
agentscope-extensions-model-openai-official, which integrates OpenAI models through the official OpenAI Java SDK (com.openai:openai-java) against the Responses API. This complements the existingagentscope-extensions-model-openaimodule, which uses a hand-rolled HTTP client against the Chat Completions API.The Responses API is OpenAI's newer interface with built-in support for reasoning models, encrypted reasoning replay across turns, structured outputs, and server-side conversation state. This module brings first-class support for those capabilities into AgentScope.
What's included
架构图
流式时序图
Module:
agentscope-extensions-model-openai-official(14 production classes, ~2,500 LOC)The module is structured around a clean separation of concerns:
OpenAIResponsesChatModel— theChatModelBaseimplementation. Owns the streaming/non-streaming dispatch, retry classification, and builder API. SDK retry is disabled (maxRetries = 0); AgentScope owns all retry logic via a module-levelretryOnpredicate that inspectsx-should-retryheaders and SDK exception types.OpenAIOfficialModelProvider— SPI provider registered viaModelProviderservice loader. Supports theopenai-official:<model>model-id convention and resolvesOPENAI_API_KEY/OPENAI_BASE_URLfrom the environment.ResponsesRequestMapper— maps AgentScopeMsgobjects,ToolSchemadefinitions, andGenerateOptionsto SDKResponseCreateParams. Handles reasoning replay (encrypted content from previous turns), structured output (JSON object / JSON schema), tool-call mapping with strict mode, and fail-fast validation for unsupported fields.ResponsesResponseParser— parses a non-streamingResponseinto a singleChatResponse, assembling content blocks in fixed order (ThinkingBlock -> TextBlock -> ToolUseBlock) with full metadata extraction.ResponsesStreamingAssembler— assembles aFlux<ResponseStreamEvent>into incrementalChatResponsechunks. Routes text deltas, reasoning summary deltas, function-call argument deltas, and terminal events (completed/incomplete/failed/error) with proper resource cleanup viadoFinally.ResponsesMultiAgentFormatter— multi-agent conversation formatter. Groups messages by type (SYSTEM, TOOL_SEQUENCE, AGENT_CONVERSATION, BYPASS), merges agent conversation messages into<history>-tagged user messages, and passes through tool sequences and system messages unchanged. Supports a customizable conversation history prompt.OpenAIErrorTranslator— normalizes SDK exceptions (OpenAIServiceException,OpenAIIoException,OpenAIRetryableException,OpenAIInvalidDataException,TimeoutException) intoOpenAIOfficialModelExceptionwith HTTP status codes preserved.OpenAISdkClientFactory— the single production entry point forOpenAIClientcreation. SetsmaxRetries = 0, injects builder-level additional headers, and fail-fasts on missing API key.OpenAIOfficialCredential— JSON-serializable credential type (openai_official_credential) for use with AgentScope's credential system.OpenAIOfficialConstants— shared constants for metadata namespace keys (openai.*) and theadditionalBodyParamswhitelist.Key capabilities:
low/medium/high/minimal) with encrypted reasoning content automatically replayed across turns viaMsg.metadata— no manual management neededadditionalBodyParams:reasoning.summary,reasoning.context,reasoning.mode,service_tier,prompt_cache_key,prompt_cache_options,max_tool_calls,safety_identifierOpenAIOfficialResponsesProvider)Supporting changes
Several improvements to core and harness modules were needed to support this integration:
ModelContextWindows— added context window sizes for GPT-5.x, GPT-6, and GLM-5.3 models.ModelUtils— timeout exceptions now wrap aTimeoutExceptionas cause, so module-levelretryOnpredicates can detect timeouts in the cause chain.agentscope-allandagentscope-bomupdated to include the new module.Testing
The module includes 13 test files totaling ~5,600 lines, covering:
Not yet supported
The following are intentionally out of scope for this initial PR. They are tracked for follow-up work:
storeparameter — hardcoded tofalseinResponsesRequestMapper. OpenAI's server-side conversation storage is not used; AgentScope manages conversation history client-side. Making this configurable is a straightforward future enhancement.TextBlock,ImageBlock(URL and base64), and image-typeDataBlockare supported.AudioBlockandVideoBlockare not mapped; the request mapper fail-fasts on unsupported block types, and the multi-agent formatter silently skips them. The existing OpenAI and DashScope modules handle audio and video blocks.ProxyConfig— not supported. This is a real gap for enterprise and restricted-network environments. The official SDK'sOpenAIOkHttpClient.Buildersupports proxy configuration, so wiring is feasible.MultiModalToolimplementation. The OpenAI module providesOpenAIMultiModalTool(text-to-image, image-to-text, text-to-audio, audio-to-text) and the DashScope module providesDashScopeMultiModalTool. A corresponding tool for this module is optional but would improve feature parity.Usage
Via explicit builder:
With reasoning and multi-agent formatter: